import { Vertex } from "../gpu/types/Vertex";
import { any, has } from "../core/logic";
import { ParamManager } from "../gpu/ParamManager";
const SkyboxPosition = new Float32Array([
  1, 1, -1,
  -1, 1, -1,
  1, -1, -1,
  -1, -1, -1,
  1, 1, 1,
  -1, 1, 1,
  1, -1, 1,
  -1, -1, 1
]);
const SkyboxIndices = new Uint16Array([
  0, 2, 1,
  2, 3, 1,
  4, 5, 6,
  5, 7, 6,
  4, 0, 5,
  0, 1, 5,
  6, 7, 2,
  7, 3, 2,
  6, 0, 4,
  6, 2, 0,
  5, 1, 7,
  1, 3, 7]);
/**
 * 材质类。
 * @class
 * @memberof w.geometry
 */
class SkyboxGeometry extends ParamManager {
  /**
   * 创建材质
   * @constructor
   * @param {*} opts
   * @param {string} opts.name 【可选】名称。
   */
  constructor(opts = {}, share) {
    super(opts, share);
    this._cameraView = any(opts.cameraView, "all");//相机的视图,缺省使用vp矩阵。
    this.type='SkyboxGeometry';
    this.geometryType = 'SkyboxGeometry';
    this._hash = '';
    this.position = SkyboxPosition;
    this.indices = SkyboxIndices
    this.autoUpdate = true;
    this.update();
  }
  get cameraView () {
    return this._cameraView;
  }
  get hash () {
    return this._hash;
  }

  get geometryType () {
    return this._geometryType;
  }
  set geometryType (v) {
    this._geometryType = v;
    this.addConfigParam("geometryType", v);
    this.update();
    return this;
  }
  set position (v) {
    this._position = v;
    this.addParam("position");
    this.update();
    return this;
  }

  get position () {
    return this._position;
  }

  set indices (v) {
    if (!has(v)) {
      return;
    }
    this._indices = v;
    this.addParam("indices");
    this.update();
    return this;
  }

  get indices () {
    return this._indices;
  }
  updateState () {
    //全部为同步状态，状态为true
    this.setState(true);
  }
  update () {
    if ((!this.autoUpdate)) {//如果父类中未更新完成，或自动更新关闭，并且不强制更新。
      return;
    }
    if (!this.getState()) {
      this.updateState();
    }
    if (!this.getState()) {
      return;
    }
    let oldhash = this.hash;
    this.updateHash();
    this.setState(oldhash != this.hash, "layout");
    this.notice();
  }
  updateHash () {
    let hash = '';
    this.getAll().forEach(([paramsId, param]) => {
      if (param && param.isConfig) {
        hash = hash + paramsId + (typeof param.value === 'object' ? JSON.stringify(param.value) : param.value);
      } else {
        hash = hash + paramsId;
      }
    })
    this._hash = hash;
  }

  initVertex (data, name, itemLength) {
    let id = `${name}`;
    let param = this.getParam(id);
    if (param && param.size != data.byteLength) {
      param.destroy();
      this.removeParam(id);
    }
    param = this.getParam(id);
    if (!param) {
      param = new Vertex({
        name,
        usage: name === 'indices' ? GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST | GPUBufferUsage.VERTEX : GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        size: data.byteLength,
        itemLength,
        data
      });
      this.addParam(id, param);
      param.state = true;
    }
  }
  toGPU () {
    if (this.has('position')) {
      this.initVertex(this.position, 'position', 3);
    }
    if (this.has('indices')) {
      this.initVertex(this.indices, 'indices', 1);
    }
    // 生成bindGroup和groupLayout 
    if (this.getState("layout")) {
      const params = this.getAllParams()
      this.defs = {}
      this.config = {}
      this.vertexBuffer = []
      this.geometryParams = []
      for (let index = 0; index < params.length; index++) {
        const param = params[index];
        this.defs[param.name] = param.value;
        if (param.group === 5) {
          this.config[param.name] = param.value
        } else {
          this.geometryParams.push(param)
          if (param.name != "indices") {
            this.vertexBuffer.push(param.gpu.layout)
          }
        }
      }
    }
  }
}

export { SkyboxGeometry, SkyboxPosition, SkyboxIndices }